package org.beetl.json;

import java.util.ArrayList;
import java.util.List;

import org.beetl.json.annotation.Json;
import org.beetl.json.annotation.JsonPolicy;
import org.beetl.json.loc.AttributeLocation;
import org.beetl.json.loc.ClassTypeLocation;
import org.beetl.json.loc.IndexLocation;
import org.beetl.json.loc.MatchFieldLocation;
import org.beetl.json.loc.PathAttributeLocation;
import org.beetl.json.loc.ThisLocation;
import org.beetl.json.loc.TypeLocation;

/** 序列化规则解析
 * @author xiandafu
 *
 */
public class PolicyParser {
	
	public static List<Location> init(Class cls,JsonTool tool){
	
		Json json = (Json)cls.getAnnotation(Json.class);
		
		if(json!=null){
			JsonPolicy[] policys = json.policys();
			List<Location> list = new ArrayList<Location>(policys.length);
			for(JsonPolicy po:policys){	
				list.add(parse(cls,po.location(),po.action(),tool));
			}	
		    Class parent = cls.getSuperclass();
		    if(!tool.isStopParse(parent.getName())){
		    	List  supers = init(parent,tool);
				list.addAll(supers);
				return list;		    
		    }
			return list;
			
		}else{
			return new ArrayList();
		}
		
	}
	
	public static Location  parse(Class c,String loc,String act,JsonTool tool){
		
		LocationAction action = null;
		Location location = null;
		//先处理位置=====
		if(loc.startsWith("~")){
			//某个指令
			String cmd = loc.substring(1);
			if(cmd.equals("n")){
				//浮点
				location = new TypeLocation(cmd);
			}else if(cmd.equals("d")){
				
				location = new TypeLocation(cmd);
			}else if(cmd.equals("*")){
				if(c==null){
//					throw new JsonException(JsonException.ERROR,"错误使用'*'来指定Location,必须具体类里");
					c = Object.class;
				}
				location = new ThisLocation(c);
				action = location.parseAction(act);
				location.setAction(action);
				location.setTool(tool);
				return location;
				
				
			}else if(cmd.equals("c")){
				location = new TypeLocation(cmd);
			}else if(cmd.startsWith("L/")){
				//某个类
				
				String clsName = cmd.substring(2,cmd.length()-1);
				if(clsName.endsWith("*")){
					location = new ClassTypeLocation(getClassByName(clsName.substring(0,clsName.length()-1),tool),false,loc+":"+act);
					
				}else{
					location = new ClassTypeLocation(getClassByName(clsName,tool),true,loc+":"+act);
				}
				
			}
			else{
				throw new UnsupportedOperationException();
			}
		}else if(loc.startsWith("[")){
			int index = loc.indexOf("]");
			String strRef = loc.substring(1,index);
			Object ref = null;
			try{
				ref = Integer.parseInt(strRef);
			}catch(Exception ex){
				ref = strRef;
			}
			if(index==loc.length()-1){		
				
				location = new IndexLocation(ref,tool.EMPTY_POLICY);	
				action = location.parseAction(act);
				location.setAction(action);
				location.setTool(tool);
				return location;
			}else{
				if(loc.charAt(index+1)=='.'){
					String newLocation = loc.substring(index+2);				
					location = new IndexLocation(ref,newLocation+":"+act);			
					return location;
				}else if( loc.charAt(index+1)=='[') {
					String newLocation = loc.substring(index+1);				
					location = new IndexLocation(ref,newLocation+":"+act);		
					location.setTool(tool);
					return location;
				}
				throw new JsonException(JsonException.ERROR, "解析错:"+loc);
			}
			
			
		}else if(loc.equals("*")){
			location = new MatchFieldLocation(loc+":"+act);
			
		}
		else{
			// 以属性名开头的，aa,aa[0].  aa[0].cc ,
			String attrName = loc;
			int index = attrName.indexOf('.');
			if(index!=-1){
				int newindex = attrName.indexOf("[");
				if(newindex!=-1){
					String attr = attrName.substring(0,newindex);
					String subLocation = attrName.substring(newindex);
					location = new PathAttributeLocation(attr,subLocation,act);
				}else{
					String attr = attrName.substring(0,index);
					String subLocation = attrName.substring(index+1);
					location = new PathAttributeLocation(attr,subLocation,act);
				}
			
			}else{
				index = attrName.indexOf("[");
				
				if(index!=-1){
					String attr = attrName.substring(0,index);
					String subLocation = attrName.substring(index);
					location = new PathAttributeLocation(attr,subLocation,act);
				}else{
					location = new AttributeLocation (attrName);
				}
						
				
			}
			
			
		}
		location.setTool(tool);
		action = location.parseAction(act);
		location.setAction(action);	
		return location;
	}
	
	
	
	
	
	protected static Class getClassByName(String clsName,JsonTool tool){
			String name  = tool.getNameByAlias(clsName);		
			try{
				return Class.forName(name);
			}catch (ClassNotFoundException e) {
				throw new JsonException(JsonException.ERROR, "找不到类"+name);
			}
		
	}
	
	
	
}
